<?php
date_default_timezone_set("Asia/Jerusalem");
chdir('..');
require('watchdog.php');
require('structure.php');
//require('remoting.php');
require('autoload.php');

abstract class remote_messenger {
    public function call($objectname, $method, $parameters) {
        //sends the other party a message and expects a respoonse
    }
    public function call_noreturn($objectname, $method) {
        //sends the other party a message
    }
    public function call_async($objectname, $method, array $callback) {
        //calls a function and registers a callback for it's reply
    }
    public function get($objectname, $method) {
        //sends the remote party a message and expects an object in return
    }
    public function get_async($objectname, $method, array $callback) {
        //sends the remote party a message and registers a callback for the reply
    }
    public function register(array $callbacks, array $localhooks) {
        //hooks up local hooks to remote callbacks until disconnected
    }
    public function set($objectname, $method, $value) {
        //sends a new value for a variable
    }
    public function isset_($objectname, $method) {
        //checks if remote variable exists
    }
    public function isset_async($objectname, $method, array $callback) {
        //checks if remote variable exists and registers a callback for the reply
    }
    
    public function parse($objectname, $method, $parameters) {
        if ($parameters == null or !is_array($parameters))
            $parameters = array();
        if (!is_string($objectname))
            throw new Exception("invalid string specified for objectname");
        if (!is_string($method))
            throw new Exception("invalid string specified for method");
        //receive a message from the client, validate if target is valid and if remotable
        if (!array_key_exists($objectname,$GLOBALS['remote']))
            //return -1;
            throw new Exception("object not remote",1);
        if (!$GLOBALS['remote'][$objectname] instanceof remote_call)
            //return -2;
            throw new Exception("object not remote_call",2);
        if (!is_callable(array(&$GLOBALS['remote'][$objectname], $method)))
            //return -3;
            throw new Exception("object not callable",3);
        return call_user_func_array(array(&$GLOBALS['remote'][$objectname], $method), $parameters);
    }
    public function lookup($objectname, $method, $parameters = null) {
        //receive a query and return a result if target is valid and if remotable
        try {
            $ret = $this->parse($objectname, $method, $parameters);
        } catch (Exception $ex) {
            if ($ex->getCode() < 1)
                throw $ex;
            $ret = null;
        }
        return $ret;
    }
    public function hookup(array $callbacks, array $remotehooks) {
        //hooks up remote hooks to local callbacks until disconnected
    }
}
interface remote_placeholder {
    public function __set ( $name, $value );
    public function __get ( $name );
    public function __isset ( $name );
    public function __unset ( $name );
    public function __call ( $name, array $arguments );
}
abstract class remote_class implements remote_placeholder {
    protected $__rmsg = null, $__rname = '';
    public function __construct($rname, remote_messenger &$rmsg) {
        $this->__rmsg =& $rmsg;
        $this->__rname = $rname;
    }
    public function __set ( $name, $value )
    {
        
    }
    public function __get ( $name )
    {
        return $this->__rmsg->query($this->__rname, $name);
    }
    public function __isset ( $name )
    {
        
    }
    public function __unset ( $name )
    {
        
    }
    public function __call ( $name, array $arguments )
    {
        return $this->__rmsg->query($this->__rname, $name, $arguments);
    }
}

/*
[server] <----------------------> [threads]
    `calllbacks events               |`register callbacks 
        /             \              `raise events
    local           remote
[basic] user channel server member(ngi+ni) community(ci) memo backgrond history personal
*/
?>